/**
 * 
 */
package com.maywide.jdp.system.service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import com.maywide.jdp.core.exception.AppException;
import com.maywide.jdp.core.utils.CryptoUtil;
import com.maywide.jdp.core.vo.Page;
import com.maywide.jdp.system.annotation.JSON;
import com.maywide.jdp.system.bean.OperatorBean;
import com.maywide.jdp.system.entities.Operator;
import com.maywide.jdp.system.entities.Organization;
import com.maywide.jdp.system.entities.Role;
import com.maywide.jdp.system.utils.JSONEditor;
import com.maywide.jdp.system.utils.PasswordEncoder;

/**
 * 用户管理Service
 * 
 * @author luoyang
 * @version 1.0
 * @since JDK1.6
 */
@Controller("operatorService")
public class OperatorServiceImpl implements OperatorService {
	private static final String APP_TYPE_BASE = "base";
	private static final String APP_TYPE_ROLES = "roles";
	private static final String APP_TYPE_ORGANIZATIONS = "organizations";

	/**
	 * 用户Bean接口
	 */
	private OperatorBean bean = null;
	
	@Autowired
	@Qualifier("passwordEncoder")
	private PasswordEncoder passwordEncoder = null;

	/**
	 * @param bean
	 *            the bean to set
	 */
	@Autowired
	@Qualifier("operatorBean")
	public void setBean(OperatorBean bean) {
		this.bean = bean;
	}

	public void setPasswordEncoder(PasswordEncoder passwordEncoder) {
		this.passwordEncoder = passwordEncoder;
	}

	@JSON
	@RequestMapping(value = "/system/operator/insert.json")
	@Override
	public Operator insert(@RequestParam(value = "operator") Operator operator,
			HttpServletRequest request, HttpServletResponse response,
			HttpSession session) throws Exception {
		String password = operator.getPassword();
		password = CryptoUtil.md5(password);
		operator.setPassword(password);
		bean.insert(operator);
		return operator;
	}

	@JSON
	@RequestMapping(value = "/system/operator/update.json")
	@Override
	public Operator update(
			@RequestParam(value = "operator") Operator operatorVO,
			HttpServletRequest request, HttpServletResponse response,
			HttpSession session) throws Exception {
		long id = operatorVO.getId();
		Operator operator = (Operator) bean.load(id);
		// 取得不可改变属性
		String password = operator.getPassword();
		operatorVO.setPassword(password);
		BeanUtils.copyProperties(operatorVO, operator);
		bean.update(operator);
		return operator;
	}

	@JSON
	@RequestMapping(value = "/system/operator/updateApp.json")
	@Override
	public Operator updateApp(
			@RequestParam(value = "operator") Operator operatorVO,
			@RequestParam(value = "appType") String appType,
			HttpServletRequest request, HttpServletResponse response,
			HttpSession session) throws Exception {
		long id = operatorVO.getId();

		if (appType.equals(APP_TYPE_BASE)) {
			Operator operator = (Operator) bean.load(id);
			// 取得不可改变属性
			String password = operator.getPassword();
			List<Role> roles = operator.getRoles();
			List<Organization> organizations = operator.getOrganizations();

			operatorVO.setPassword(password);
			operatorVO.setRoles(roles);
			operatorVO.setOrganizations(organizations);

			BeanUtils.copyProperties(operatorVO, operator);
			bean.update(operator);
			return operator;
		} else if (appType.equals(APP_TYPE_ROLES)) {
			List<Role> roles = operatorVO.getRoles();
			Operator operator = (Operator) bean.load(id);
			operator.setRoles(roles);
			bean.update(operator);
			return operator;
		} else if (appType.equals(APP_TYPE_ORGANIZATIONS)) {
			List<Organization> organizations = operatorVO.getOrganizations();
			Operator operator = (Operator) bean.load(id);
			operator.setOrganizations(organizations);
			bean.update(operator);
			return operator;
		} else {
			throw new Exception("未知的应用类型!");
		}
	}

	@JSON
	@RequestMapping(value = "/system/operator/load.json")
	@Override
	public Operator load(@RequestParam(value = "id") Long id,
			HttpServletRequest request, HttpServletResponse response,
			HttpSession session) throws Exception {
		Operator operator = (Operator) bean.load(id);
		return operator;
	}

	@RequestMapping(value = "/system/operator/lock.json")
	@Override
	public void lock(@RequestParam(value = "id") String id,
			HttpServletRequest request, HttpServletResponse response,
			HttpSession session) throws Exception {
		bean.lock(id);
	}

	@RequestMapping(value = "/system/operator/unlock.json")
	@Override
	public void unlock(@RequestParam(value = "id") String id,
			HttpServletRequest request, HttpServletResponse response,
			HttpSession session) throws Exception {
		bean.unlock(id);
	}

	@RequestMapping(value = "/system/operator/changePassword.json")
	@Override
	public void changePassword(@RequestParam(value = "id") Long id,
			@RequestParam(value = "newPassword") String newPassword,
			HttpServletRequest request, HttpServletResponse response,
			HttpSession session) throws Exception {
		Operator operator = (Operator) bean.load(id);
		String password = this.passwordEncoder.encode(newPassword);
		operator.setPassword(password);
		bean.update(operator);
	}

	@RequestMapping(value = "/system/operator/changeSelfPassword.json")
	@Override
	public void changeSelfPassword(
			@RequestParam(value = "operatorID") String operatorID,
			@RequestParam(value = "prePassword") String prePassword,
			@RequestParam(value = "newPassword") String newPassword,
			HttpServletRequest request, HttpServletResponse response,
			HttpSession session) throws Exception {
		Operator operator = (Operator) bean.load(operatorID);
		if (!this.passwordEncoder.encode(prePassword.trim()).equals(operator.getPassword()))
			throw new AppException("旧密码错误!");
		operator.setPassword(this.passwordEncoder.encode(newPassword));
		update(operator, request, response, session);
	}

	@RequestMapping(value = "/system/operator/move.json")
	@Override
	public void move(@RequestParam(value = "ids") List<String> ids,
			@RequestParam(value = "oldID") String oldID,
			@RequestParam(value = "targetID") String targetID,
			HttpServletRequest request, HttpServletResponse response,
			HttpSession session) throws Exception {
		bean.move(ids, oldID, targetID);
	}

	@JSON
	@RequestMapping(value = "/system/operator/list.json")
	public List<Operator> list(
			@RequestParam(value = "sort", defaultValue = "o.operatorID") String sort,
			@RequestParam(value = "dir", defaultValue = "ASC") String dir,
			@RequestParam(value = "organizationID", required = false) String organizationID,
			@RequestParam(value = "roleID", required = false) String roleID,
			@RequestParam(value = "active", required = false) String active,
			HttpServletRequest request, HttpServletResponse response,
			HttpSession session) throws Exception {
		Map<String, Object> conditions = new HashMap<String, Object>();
		if (active != null)
			conditions.put("active", Boolean.parseBoolean(active));

		if (organizationID != null && !"oper_org_root".equals(organizationID))
			conditions.put("organizationID", organizationID);

		if (roleID != null)
			conditions.put("roleID", roleID);

		return (List<Operator>) bean.list(sort, dir, conditions, null);
	}

	@JSON
	@RequestMapping(value = "/system/operator/page.json")
	public Page page(
			@RequestParam(value = "first", defaultValue = "0") int first,
			@RequestParam(value = "limit", defaultValue = "20") int limit,
			@RequestParam(value = "sort", defaultValue = "o.operatorID") String sort,
			@RequestParam(value = "dir", defaultValue = "ASC") String dir,
			@RequestParam(value = "organizationID", required = false) String organizationID,
			@RequestParam(value = "roleID", required = false) String roleID,
			@RequestParam(value = "key", required = false) String key,
			@RequestParam(value = "active", required = false) String active,
			@RequestParam(value = "operatorID", required = false) String operatorID,
			@RequestParam(value = "operatorname", required = false) String operatorname,
			@RequestParam(value = "mobile", required = false) String mobile,
			@RequestParam(value = "phone", required = false) String phone,
			@RequestParam(value = "email", required = false) String email,
			HttpServletRequest request, HttpServletResponse response,
			HttpSession session) throws Exception {
		Map<String, Object> conditions = new HashMap<String, Object>();
		if (key != null) {
			key = new StringBuffer("%").append(key).append("%").toString();
			conditions.put("key", key);
		}

		if (active != null)
			conditions.put("active", Boolean.parseBoolean(active));

		if (organizationID != null && !"oper_org_root".equals(organizationID))
			conditions.put("organizationID", organizationID);

		if (operatorID != null) {
			operatorID = new StringBuffer("%").append(operatorID).append("%")
					.toString();
			conditions.put("operatorID", operatorID);
		}
		if (operatorname != null) {
			operatorname = new StringBuffer("%").append(operatorname).append(
					"%").toString();
			conditions.put("operatorname", operatorname);
		}
		if (mobile != null) {
			mobile = new StringBuffer("%").append(mobile).append("%")
					.toString();
			conditions.put("mobile", mobile);
		}
		if (phone != null) {
			phone = new StringBuffer("%").append(phone).append("%").toString();
			conditions.put("phone", phone);
		}
		if (email != null) {
			email = new StringBuffer("%").append(email).append("%").toString();
			conditions.put("email", email);
		}

		if (roleID != null)
			conditions.put("roleID", roleID);

		return bean.page(first, limit, sort, dir, conditions, null);
	}

	@InitBinder
	protected void initBinder(WebDataBinder binder) {
		binder.registerCustomEditor(Operator.class, new JSONEditor(
				Operator.class));
		binder.registerCustomEditor(Organization.class, new JSONEditor(
				Organization.class));
	}

}
